1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef HTTPCONNECTION_H
#define HTTPCONNECTION_H

#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/epoll.h>
#include <fcntl.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <assert.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <stdarg.h>
#include <errno.h>
#include "locker.h"

class http_conn
{
public:
static const int FILENAME_LEN = 200;
static const int READ_BUFFER_SIZE = 2048;
static const int WRITE_BUFFER_SIZE = 1024;
enum METHOD { GET = 0, POST, HEAD, PUT, DELETE, TRACE, OPTIONS, CONNECT, PATCH };
enum CHECK_STATE { CHECK_STATE_REQUESTLINE = 0, CHECK_STATE_HEADER, CHECK_STATE_CONTENT };
enum HTTP_CODE { NO_REQUEST, GET_REQUEST, BAD_REQUEST, NO_RESOURCE, FORBIDDEN_REQUEST, FILE_REQUEST, INTERNAL_ERROR, CLOSED_CONNECTION };
enum LINE_STATUS { LINE_OK = 0, LINE_BAD, LINE_OPEN };

public:
http_conn() {}
~http_conn() {}

public:
void init(int sockfd, const sockaddr_in& addr);
void close_conn(bool real_close = true);
void process();
bool read();
bool write();

private:
void init();
HTTP_CODE process_read();
bool process_write(HTTP_CODE ret);

HTTP_CODE parse_request_line(char* text);
HTTP_CODE parse_headers(char* text);
HTTP_CODE parse_content(char* text);
HTTP_CODE do_request();
char* get_line() { return m_read_buf + m_start_line; }
LINE_STATUS parse_line();

void unmap();
bool add_response(const char* format, ...);
bool add_content(const char* content);
bool add_status_line(int status, const char* title);
bool add_headers(int content_length);
bool add_content_length(int content_length);
bool add_linger();
bool add_blank_line();

public:
static int m_epollfd;
static int m_user_count;

private:
int m_sockfd;
sockaddr_in m_address;

char m_read_buf[READ_BUFFER_SIZE];
int m_read_idx;
int m_checked_idx;
int m_start_line;
char m_write_buf[WRITE_BUFFER_SIZE];
int m_write_idx;

CHECK_STATE m_check_state;
METHOD m_method;

char m_real_file[FILENAME_LEN];
char* m_url;
char* m_version;
char* m_host;
int m_content_length;
bool m_linger;

char* m_file_address;
struct stat m_file_stat;
struct iovec m_iv[2];
int m_iv_count;
};

#endif

int main()
{
return 0;
}

 评论